﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using SuppKids.Core.Data;
using SuppKids.Core.Domain;

namespace SuppKids.Core.Repository
{
    public abstract class BaseRepository<T> : IRepository<T> where T : Entity
	{
		private IDataContext context;

		protected BaseRepository(IDataContext context)
		{
			this.context = context;
		}

		public IDataContext Context
		{
			get { return this.context; }
		}

		public abstract IQueryable<T> GetQuery();

		public abstract IEnumerable<T> GetAll(params Expression<Func<T, object>>[] includes);

		public abstract IEnumerable<T> GetAll(Expression<Func<T, bool>> whereCondition, params Expression<Func<T, object>>[] includes);

		public abstract IEnumerable<T> GetPage<TKey>(int pageNumber, int pageSize, out int totalCount, Expression<Func<T, bool>> whereCondition, Expression<Func<T, TKey>> orderBy, bool orderByAscending = true, params Expression<Func<T, object>>[] includes);

		public abstract IEnumerable<T> GetPage<TKey>(int pageNumber, int pageSize, out int totalCount, Expression<Func<T, bool>> whereCondition, Func<IQueryable<T>, IQueryable<T>> orderByClause = null, params Expression<Func<T, object>>[] includes);

		public abstract IEnumerable<T> GetPageOrderedById(int pageNumber, int pageSize, out int totalCount);

		public abstract T SingleOrDefault(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes);

		public abstract T FirstOrDefault(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes);

		public abstract T FirstOrDefault(int id);

		public abstract void Add(T entity);

		public abstract void Delete(T entity);

		public abstract void Attach(T entity);

		public abstract void Update(T entity);

		public void SaveChanges()
		{
			this.context.Commit();
		}

		public void Dispose()
		{
			this.context = null;
		}
	}
}